// --------------------------------------------------------------------------------------------------------------------- 
// <copyright file="TransitionRulesCollection.cs" company="Scrum for Team System">
//   None
// </copyright>
// <summary>
//   Defines the TransitionRulesCollection type.
// </summary>
// ---------------------------------------------------------------------------------------------------------------------
namespace ScrumForTeamSystem.EventService.TransitionService.DataStructures
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.Linq;
    using System.Xml.Serialization;

    using Infrastructure;
    using Infrastructure.Interfaces;

    /// <summary>
    /// Defines the TransitionRulesCollection type.
    /// </summary>
    [XmlRoot(Namespace = "http://schemas.ScrumForTeamSystem.com/TransitionService/RulesCollection")]
    public class TransitionRulesCollection : Collection<TransitionRule>, IRulesCollection<TransitionRule>
    {
        /// <summary>
        /// Gets the matching rules.
        /// </summary>
        /// <param name="workItemChangedEvent">The work item changed event.</param>
        /// <returns>A collection of rules that match the change event.</returns>
        public IEnumerable<TransitionRule> GetMatchingRules(WorkItemChangedEvent workItemChangedEvent)
        {
            if (workItemChangedEvent == null)
            {
                throw new ArgumentNullException("workItemChangedEvent");
            }

            var workItemTypeName = workItemChangedEvent.GetStringFieldValue(ConstantStrings.WorkItemTypeCoreField);

            var stringFields = workItemChangedEvent.ChangedFields == null ? null : workItemChangedEvent.ChangedFields.StringFields;

            var intFields = workItemChangedEvent.ChangedFields == null ? null : workItemChangedEvent.ChangedFields.IntegerFields;

            var transitions = new List<Transition>();

            if (stringFields != null)
            {
                transitions.AddRange(stringFields.Select(f => new Transition(f.ReferenceName, f.OldValue, f.NewValue)));
            }

            if (intFields != null)
            {
                transitions.AddRange(intFields.Select(f => new Transition(f.ReferenceName, f.OldValue.ToString(CultureInfo.InvariantCulture), f.NewValue.ToString(CultureInfo.InvariantCulture))));
            }

            return
                    this.Where(
                            r =>
                            r.WorkItemTypeName.Source.Equals(workItemTypeName) && transitions.Contains(r.Transition));
        }

        /// <summary>
        /// Gets all sync rules.
        /// </summary>
        /// <param name="workItemTypeName">Name of the work item type.</param>
        /// <returns>A collection of all rules that can be used for syncronisations.</returns>
        public IEnumerable<TransitionRule> GetAllSyncRules(string workItemTypeName)
        {
            return
                this.Where(
                    r =>
                    !r.IsExcludedFromSynchronisation &&
                    r.WorkItemTypeName.Target.Equals(workItemTypeName));
        }
    }
}